package com.adcc.msgsimulator.service.impl;

import com.adcc.msgsimulator.bo.Msg618BO;
import com.adcc.msgsimulator.dto.Msg618Converter;
import com.adcc.msgsimulator.entity.DownLinkMsgDO;
import com.adcc.msgsimulator.entity.Msg618DO;
import com.adcc.msgsimulator.entity.UpLinkMsgDO;
import com.adcc.msgsimulator.mapper.Msg618Mapper;
import com.adcc.msgsimulator.service.DownLinkMsgService;
import com.adcc.msgsimulator.service.Msg618Service;
import com.adcc.msgsimulator.service.UpLinkMsgService;
import com.adcc.msgsimulator.util.ConfigMapUtil;
import com.adcc.msgsimulator.util.MsgType;
import com.adcc.msgsimulator.util.PropertiesUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Optional;

/**
 * msg618服务层
 */
@Service
@Slf4j
//@SuppressWarnings("all")
public class Msg618ServiceImpl extends ServiceImpl<Msg618Mapper, Msg618DO> implements Msg618Service {

    @Resource
    private Msg618Converter msg618Converter;

    @Autowired
    private DownLinkMsgService downLinkMsgService;

    @Autowired
    private UpLinkMsgService uplinkMsgService;

    @Override
    public void save(Msg618BO msg618) throws Exception {
        try {
            Msg618DO ldo = msg618Converter.toDO(msg618);

            if (!this.saveOrUpdate(ldo)) {
                throw new Exception("save or update failed");
            }
        } catch (Exception ex) {
            log.error("save() error", ex);
        }
    }

    @Override
    public void selectDownLink() throws Exception {
        try {
            //获取下行报对应的时间
            String updateTime = ConfigMapUtil.get("t_downlink_date");
            // 判断更新时间是否为空
            if (Strings.isNullOrEmpty(updateTime)) {
                //从two所有的下行信息
                List<DownLinkMsgDO> linkMsgs = downLinkMsgService.list(new QueryWrapper<DownLinkMsgDO>().orderByAsc("ID"));

                // 获取最后一条数据
                Optional<DownLinkMsgDO> downLinkMsgOptional = linkMsgs.stream().skip(linkMsgs.size() - 1).findFirst();
                linkMsgs.forEach(down -> {
                    if (StringUtils.isNotBlank(down.getMsgId())) {
                        //存数据
                        savDownLinkeMsg618(down);
                    }
                });
                if (downLinkMsgOptional.isPresent()) {
                    String date = downLinkMsgOptional.get().getUpdateTime();
                    // 更新时间进行properties存储
                    upProperties(MsgType.DOWNLINK.name(), date);
                }
            } else {
                // 更新时间不为空根据时间查询新一批数据
                QueryWrapper<DownLinkMsgDO> queryWrapper = new QueryWrapper<>();
                queryWrapper.ge("update_Time", updateTime).and(v -> v.le("update_Time", DateTime.now(DateTimeZone.UTC).toString("yyyy-MM-dd HH:mm:ss")));
                queryWrapper.orderByAsc("ID");
                //取出符合条件的下信息
                List<DownLinkMsgDO> list = downLinkMsgService.list(queryWrapper);
                list.forEach(down -> {
                    if (StringUtils.isNotBlank(down.getMsgId())) {
                        savDownLinkeMsg618(down);
                    }
                });
                List<DownLinkMsgDO> linkMsgs = downLinkMsgService.list();
                Optional<DownLinkMsgDO> downLinkMsgOptional = linkMsgs.stream().skip(linkMsgs.size() - 1).findFirst();
                if (downLinkMsgOptional.isPresent()) {
                    String date = downLinkMsgOptional.get().getUpdateTime();
                    upProperties(MsgType.DOWNLINK.name(), date);
                }
            }
        } catch (Exception ex) {
            log.error("selectDownLink() error", ex);
        }
    }

    @Override
    public void selectUpLink() throws Exception {
        try {
            String updateTime = ConfigMapUtil.get("t_uplink_date");
            // 判断更新时间是否为空
            if (Strings.isNullOrEmpty(updateTime)) {
                //按照id排序
                List<UpLinkMsgDO> linkMsgs = uplinkMsgService.list(new QueryWrapper<UpLinkMsgDO>().orderByAsc("ID"));

                // 获取最后一条数据
                Optional<UpLinkMsgDO> upLinkMsgOptional = linkMsgs.stream().skip(linkMsgs.size() - 1).findFirst();
                linkMsgs.forEach(up -> {
                    if (StringUtils.isNotBlank(up.getMsgId())) {
                        saveUpLinkMsg618(up);
                    }
                });
                if (upLinkMsgOptional.isPresent()) {
                    String date = upLinkMsgOptional.get().getUpdateTime();
                    // 更新时间进行properties存储
                    upProperties(MsgType.UPLINK.name(), date);
                }
            } else {
                // 更新时间不为空根据时间查询新一批数据
                QueryWrapper<UpLinkMsgDO> queryWrapper = new QueryWrapper<>();
                queryWrapper.ge("update_Time", updateTime).and(v -> v.le("update_Time", DateTime.now(DateTimeZone.UTC).toString("yyyy-MM-dd HH:mm:ss")));
                queryWrapper.orderByAsc("ID");
                List<UpLinkMsgDO> list = uplinkMsgService.list(queryWrapper);
                list.forEach(up -> {
                    if (StringUtils.isNotBlank(up.getMsgId())) {
                        saveUpLinkMsg618(up);
                    }
                });
                List<UpLinkMsgDO> linkMsgs = uplinkMsgService.list();
                Optional<UpLinkMsgDO> upLinkMsgOptional = linkMsgs.stream().skip(linkMsgs.size() - 1).findFirst();
                if (upLinkMsgOptional.isPresent()) {
                    String date = upLinkMsgOptional.get().getUpdateTime();
                    upProperties(MsgType.UPLINK.name(), date);
                }
            }
        } catch (Exception ex) {
            log.error("selectUpLink() error", ex);
        }
    }

    public void savDownLinkeMsg618(DownLinkMsgDO down) {
        List<Msg618DO> list = this.list(new LambdaQueryWrapper<Msg618DO>().select(Msg618DO::getMsgID).eq(Msg618DO::getMsgType, 0).eq(Msg618DO::getMsgID, down.getMsgId()));
        //是否已经存在数据库
        if (list.size() != 0) {
            return;
        }
        Msg618DO msg618 = new Msg618DO();
        msg618.setMsgID(down.getMsgId());
        msg618.setRecvTime(down.getCreateTime());
        // TODO 表字段映射不对,dep_time是什么时间。
        msg618.setMsgType(0);
        msg618.setStation(down.getStation());
        msg618.setTail(down.getAn());
        if (!Strings.isNullOrEmpty(down.getFn())) {
            String agency = down.getFn().substring(0, 2);
            msg618.setAgency(agency);
            msg618.setFlightNum(down.getFn());
        }
        msg618.setLabel(down.getLabel());
        msg618.setBi(down.getDbi());
        msg618.setTak(down.getTak());
        msg618.setMsgLength(down.getRawMsg().length());
        msg618.setMsg(down.getRawMsg());
        msg618.setMsn(down.getMsn());
        this.save(msg618);
    }

    public void saveUpLinkMsg618(UpLinkMsgDO up) {
        List<Msg618DO> list = this.list(new LambdaQueryWrapper<Msg618DO>().select(Msg618DO::getMsgID).eq(Msg618DO::getMsgType, 1).eq(Msg618DO::getMsgID, up.getMsgId()));
        //是否已经存在数据库
        if (list.size() != 0) {
            return;
        }
        Msg618DO msg618 = new Msg618DO();
        msg618.setMsgID(up.getMsgId());
        msg618.setRecvTime(up.getCreateTime());
        msg618.setMsgType(1);
        msg618.setStation(up.getStation());
        msg618.setTail(up.getAn());
        if (!Strings.isNullOrEmpty(up.getFn())) {
            String agency = up.getFn().substring(0, 2);
            msg618.setAgency(agency);
            msg618.setFlightNum(up.getFn());
        }
        msg618.setLabel(up.getLabel());
        msg618.setBi(up.getUbi());
        msg618.setTak(up.getTak());
        msg618.setMsgLength(up.getRawMsg().length());
        msg618.setMsg(up.getRawMsg());
        this.save(msg618);
    }

    public void upProperties(String msgType, String date) {
        if (msgType.equals(MsgType.UPLINK.name())) {
            ConfigMapUtil.update("t_uplink_date", date);
        } else {
            ConfigMapUtil.update("t_downlink_date", date);
        }
    }

}
